package com.octopus.optiworks.service;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jbpm.api.Execution;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.octopus.optiworks.action.StepActionUtil;
import com.octopus.optiworks.controller.InitProcessCommand;
import com.octopus.optiworks.controller.SearchCommand;
import com.octopus.optiworks.dao.*;
import com.octopus.optiworks.model.*;

@SuppressWarnings("restriction")
@Service
@Transactional
public class StepService {
	
	private static Log log = LogFactory.getLog(StepService.class);
	
	@Resource
	private ProcessEngine processEngine;
	
	@Resource
	private UserService userService;
	
	@Resource
	private TemplateDao templateDao;
	
	@Resource
	private StepSpecDao stepSpecDao;
	
	@Resource
	private ProductDao productDao;
	
	@Resource
	private Step10_1DataDao step10_1DataDao;
	
	@Resource
	private Step10_2DataDao step10_2DataDao;
	
	@Resource
	private Step20DataDao step20DataDao;
	
	@Resource
	private Step30_1DataDao step30_1DataDao;
	
	@Resource
	private Step30_2DataDao step30_2DataDao;
	
	@Resource
	private Step40DataDao step40DataDao;
	
	@Resource
	private Step50DataDao step50DataDao;
	
	@Resource
	private Step60DataDao step60DataDao;
	
	@Resource
	private Step70DataDao step70DataDao;
	
	@Resource
	private Step80DataDao step80DataDao;
	
	@Resource
	private Step90DataDao step90DataDao;
	
	@Resource
	private Step100_1DataDao step100_1DataDao;
	
	@Resource
	private Step100_2DataDao step100_2DataDao;
	
	@Resource
	private Step100_3DataDao step100_3DataDao;
	
	@Resource
	private Step110DataDao step110DataDao;
	
	@Resource
	private Step120_1DataDao step120_1DataDao;
	
	@Resource
	private Step120_2DataDao step120_2DataDao;
	
	@Resource
	private Step130DataDao step130DataDao;
	
	@Resource
	private Step140_1DataDao step140_1DataDao;
	
	@Resource
	private Step140_2DataDao step140_2DataDao;
	
	@Resource
	private Step140IntegrationDataDao step140IntegrationDataDao;
	
	@Resource
	private Step150DataDao step150DataDao;
	
	@Resource
	private Step160DataDao step160DataDao;
	
	@Resource
	private Step170_1DataDao step170_1DataDao;
	
	@Resource
	private Step170_2DataDao step170_2DataDao;
	
	@Resource
	private Step180DataDao step180DataDao;
	
	@Resource
	private DataSheetDao dataSheetDao;
	
	public List<ProcessInstance> getAllProcesses(){
		ExecutionService executionService = processEngine.getExecutionService();
		List<ProcessInstance> list = executionService.createProcessInstanceQuery().list();
		return list;
	}
	
	public List<Product> getAllProducts(){
		return this.productDao.loadAll();
	}
	
	public List<Product> getProductsByPermissions(SearchCommand command){
		List<Product> list = null;
		SearchCommand search = command;
		if(search == null){
			search = new SearchCommand();
		}
		search.setPermissons(this.getFilterSteps());
		this.productDao.getProductsBySearchCount(search);
		list = this.productDao.getProductsBySearch(search);
		return list;
	}
	
	public int countProductsByPermissions(SearchCommand command){
		SearchCommand search = command;
		if(search == null){
			search = new SearchCommand();
		}
		search.setPermissons(this.getFilterSteps());
		return this.productDao.getProductsBySearchCount(search);
	}
	
	public List<Product> getProductsNoPermissions(SearchCommand command){
		command.setPermissons(null);
		this.productDao.getProductsBySearchCount(command);
		return this.productDao.getProductsBySearch(command);
	}
	
	public void archiveProducts(SearchCommand command){
		this.productDao.archiveProducts(command);
	}
	
	public void unarchiveProducts(SearchCommand command){
		this.productDao.unarchiveProducts(command);
	}
	
	private List<String> getFilterSteps(){
		Employee user = this.userService.getCurrentUser();
		List<String> permissions = new ArrayList<String>(user.getPermissions());
		List<String> steps = new ArrayList<String>();
		for(String permission : permissions){
			if(permission.indexOf("step") != 0 || permission.indexOf(":") == -1)
				continue;
			String action = "";
			String scope = "";
			if(permission.indexOf(":") == permission.lastIndexOf(":")){
				action = permission.substring(permission.indexOf(":") + 1);
			}else{
				action = permission.substring(permission.indexOf(":") + 1, permission.lastIndexOf(":"));
				scope = permission.substring(permission.lastIndexOf(":") + 1);
			}
			if(action.equals("*") || action.equals("manage") || (action.equals("input") && (scope.equals("*") || scope.equals("")))){
				return null;
			}else if(action.equals("input"))
				steps.add(scope);
		}
		return steps;
	}
	
	public Product newProduct(InitProcessCommand command){
		return this.newProduct(command, false);
	}
	
	public Product newProduct(InitProcessCommand command, boolean dumy){
		Product current = null;
		Template template = this.getTemplate(command.getTemplate().getId());
		ExecutionService executionService = processEngine.getExecutionService();
        //Deploy a Process
        String deploymentId = processEngine.getRepositoryService().createDeployment().addResourceFromClasspath("StepLifeCycle.jpdl.xml").deploy();
        log.debug("Process Deploy ID:"+deploymentId);
		boolean flagCurrent = false;
		Product lotProduct = null;
		//Check lot properties initial
		List<Product> lotProducts = null;
		if(command.getLot() != null && command.getLot().trim().length() > 0)
			lotProducts = this.productDao.getProductsByLot(command.getLot());
		if(lotProducts != null && lotProducts.size() > 0)
			lotProduct = lotProducts.get(0);
		//Create Product
		for(int i = 0; i < new Integer(command.getNumber()); i++){
			Product product = new Product();
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", new Locale("en"));
			try {
				product.setCreateDate(format.parse(format.format(new Date())));
			} catch (ParseException e) {
				e.printStackTrace();
			}
			product.setLot(command.getLot());
			product.setTemplate(command.getTemplate());
			product.setStepSpecId(command.getStepSpecId());
			if(!flagCurrent){
				current = product;
				flagCurrent = true;
			}
			this.initLotProperties(product, lotProduct, this.getLotSynProperties(product));
	        //Start up a Process Instance
	        ProcessInstance processInstance = executionService.startProcessInstanceByKey("OPTIDWDM");
	        executionService.setVariable(processInstance.getId(), "scope", template.getSteps());
	        executionService.setVariable(processInstance.getId(), "spec", product.getStepSpecId());
	        log.debug("Start Process Instance:" + processInstance.getId());
	        product.setProcessId(processInstance.getId());
	        Set<String> status = this.findActiveActivityNames(processInstance.getId());
	        product.setStatus(status.toArray()[0].toString());
	        
	        if(template.getSteps().contains("step10_1")){
		        Step10_1Data step10_1Data = new Step10_1Data();
		        step10_1Data.setProduct(product);
		        product.setStep10_1Datas(new HashSet<Step10_1Data>());
		        product.getStep10_1Datas().add(step10_1Data);
		        Set<Step10_1Data> lotStep10_1Datas = null == lotProduct? null : lotProduct.getStep10_1Datas();
		        if(lotStep10_1Datas != null && lotStep10_1Datas.size() > 0)
		        	this.initLotProperties(step10_1Data, lotStep10_1Datas.toArray()[0], this.getLotSynProperties(step10_1Data));
	        }
	        
	        if(template.getSteps().contains("step10_2")){
		        Step10_2Data step10_2Data = new Step10_2Data();
		        step10_2Data.setProduct(product);
		        product.setStep10_2Datas(new HashSet<Step10_2Data>());
		        product.getStep10_2Datas().add(step10_2Data);
		        Set<Step10_2Data> lotStep10_2Datas = null == lotProduct? null : lotProduct.getStep10_2Datas();
		        if(lotStep10_2Datas != null && lotStep10_2Datas.size() > 0)
		        	this.initLotProperties(step10_2Data, lotStep10_2Datas.toArray()[0], this.getLotSynProperties(step10_2Data));
	        }
	        
	        if(template.getSteps().contains("step20")){
		        Step20Data step20Data = new Step20Data();
		        step20Data.setProduct(product);
		        product.setStep20Datas(new HashSet<Step20Data>());
		        product.getStep20Datas().add(step20Data);
		        Set<Step20Data> lotStep20Datas = null == lotProduct? null : lotProduct.getStep20Datas();
		        if(lotStep20Datas != null && lotStep20Datas.size() > 0)
		        	this.initLotProperties(step20Data, lotStep20Datas.toArray()[0], this.getLotSynProperties(step20Data));
	        }
	        
	        if(template.getSteps().contains("step30_1")){
		        Step30_1Data step30_1Data = new Step30_1Data();
		        step30_1Data.setProduct(product);
		        product.setStep30_1Datas(new HashSet<Step30_1Data>());
		        product.getStep30_1Datas().add(step30_1Data);
		        Set<Step30_1Data> lotStep30_1Datas = null == lotProduct? null : lotProduct.getStep30_1Datas();
		        if(lotStep30_1Datas != null && lotStep30_1Datas.size() > 0)
		        	this.initLotProperties(step30_1Data, lotStep30_1Datas.toArray()[0], this.getLotSynProperties(step30_1Data));
	        }
	        
	        if(template.getSteps().contains("step30_2")){
		        Step30_2Data step30_2Data = new Step30_2Data();
		        step30_2Data.setProduct(product);
		        product.setStep30_2Datas(new HashSet<Step30_2Data>());
		        product.getStep30_2Datas().add(step30_2Data);
		        Set<Step30_2Data> lotStep30_2Datas = null == lotProduct? null : lotProduct.getStep30_2Datas();
		        if(lotStep30_2Datas != null && lotStep30_2Datas.size() > 0)
		        	this.initLotProperties(step30_2Data, lotStep30_2Datas.toArray()[0], this.getLotSynProperties(step30_2Data));
	        }
	        
	        if(template.getSteps().contains("step40")){
		        Step40Data step40Data = new Step40Data();
		        step40Data.setProduct(product);
		        product.setStep40Datas(new HashSet<Step40Data>());
		        product.getStep40Datas().add(step40Data);
		        Set<Step40Data> lotStep40Datas = null == lotProduct? null : lotProduct.getStep40Datas();
		        if(lotStep40Datas != null && lotStep40Datas.size() > 0)
		        	this.initLotProperties(step40Data, lotStep40Datas.toArray()[0], this.getLotSynProperties(step40Data));
	        }
	        
	        if(template.getSteps().contains("step50")){
		        Step50Data step50Data = new Step50Data();
		        step50Data.setProduct(product);
		        product.setStep50Datas(new HashSet<Step50Data>());
		        product.getStep50Datas().add(step50Data);
		        Set<Step50Data> lotStep50Datas = null == lotProduct? null : lotProduct.getStep50Datas();
		        if(lotStep50Datas != null && lotStep50Datas.size() > 0)
		        	this.initLotProperties(step50Data, lotStep50Datas.toArray()[0], this.getLotSynProperties(step50Data));
	        }
	        
	        if(template.getSteps().contains("step60")){
		        Step60Data step60Data = new Step60Data();
		        step60Data.setProduct(product);
		        product.setStep60Datas(new HashSet<Step60Data>());
		        product.getStep60Datas().add(step60Data);
		        Set<Step60Data> lotStep60Datas = null == lotProduct? null : lotProduct.getStep60Datas();
		        if(lotStep60Datas != null && lotStep60Datas.size() > 0)
		        	this.initLotProperties(step60Data, lotStep60Datas.toArray()[0], this.getLotSynProperties(step60Data));
	        }
	        
	        if(template.getSteps().contains("step70")){
		        Step70Data step70Data = new Step70Data();
		        step70Data.setProduct(product);
		        product.setStep70Datas(new HashSet<Step70Data>());
		        product.getStep70Datas().add(step70Data);
		        Set<Step70Data> lotStep70Datas = null == lotProduct? null : lotProduct.getStep70Datas();
		        if(lotStep70Datas != null && lotStep70Datas.size() > 0)
		        	this.initLotProperties(step70Data, lotStep70Datas.toArray()[0], this.getLotSynProperties(step70Data));
	        }
	        
	        if(template.getSteps().contains("step80")){
		        Step80Data step80Data = new Step80Data();
		        step80Data.setProduct(product);
		        product.setStep80Datas(new HashSet<Step80Data>());
		        product.getStep80Datas().add(step80Data);
		        Set<Step80Data> lotStep80Datas = null == lotProduct? null : lotProduct.getStep80Datas();
		        if(lotStep80Datas != null && lotStep80Datas.size() > 0)
		        	this.initLotProperties(step80Data, lotStep80Datas.toArray()[0], this.getLotSynProperties(step80Data));
	        }
	        
	        if(template.getSteps().contains("step90")){
		        Step90Data step90Data = new Step90Data();
		        step90Data.setProduct(product);
		        product.setStep90Datas(new HashSet<Step90Data>());
		        product.getStep90Datas().add(step90Data);
		        Set<Step90Data> lotStep90Datas = null == lotProduct? null : lotProduct.getStep90Datas();
		        if(lotStep90Datas != null && lotStep90Datas.size() > 0)
		        	this.initLotProperties(step90Data, lotStep90Datas.toArray()[0], this.getLotSynProperties(step90Data));
	        }
	        
	        if(template.getSteps().contains("step100_1")){
		        Step100_1Data step100_1Data = new Step100_1Data();
		        step100_1Data.setProduct(product);
		        product.setStep100_1Datas(new HashSet<Step100_1Data>());
		        product.getStep100_1Datas().add(step100_1Data);
		        Set<Step100_1Data> lotStep100_1Datas = null == lotProduct? null : lotProduct.getStep100_1Datas();
		        if(lotStep100_1Datas != null && lotStep100_1Datas.size() > 0)
		        	this.initLotProperties(step100_1Data, lotStep100_1Datas.toArray()[0], this.getLotSynProperties(step100_1Data));
	        }
	        
	        if(template.getSteps().contains("step100_2")){
		        Step100_2Data step100_2Data = new Step100_2Data();
		        step100_2Data.setProduct(product);
		        product.setStep100_2Datas(new HashSet<Step100_2Data>());
		        product.getStep100_2Datas().add(step100_2Data);
		        Set<Step100_2Data> lotStep100_2Datas = null == lotProduct? null : lotProduct.getStep100_2Datas();
		        if(lotStep100_2Datas != null && lotStep100_2Datas.size() > 0)
		        	this.initLotProperties(step100_2Data, lotStep100_2Datas.toArray()[0], this.getLotSynProperties(step100_2Data));
	        }
	        
	        if(template.getSteps().contains("step100_3")){
		        Step100_3Data step100_3Data = new Step100_3Data();
		        step100_3Data.setProduct(product);
		        product.setStep100_3Datas(new HashSet<Step100_3Data>());
		        product.getStep100_3Datas().add(step100_3Data);
		        Set<Step100_3Data> lotStep100_3Datas = null == lotProduct? null : lotProduct.getStep100_3Datas();
		        if(lotStep100_3Datas != null && lotStep100_3Datas.size() > 0)
		        	this.initLotProperties(step100_3Data, lotStep100_3Datas.toArray()[0], this.getLotSynProperties(step100_3Data));
	        }
	        
	        if(template.getSteps().contains("step110")){
		        Step110Data step110Data = new Step110Data();
		        step110Data.setProduct(product);
		        product.setStep110Datas(new HashSet<Step110Data>());
		        product.getStep110Datas().add(step110Data);
		        Set<Step110Data> lotStep110Datas = null == lotProduct? null : lotProduct.getStep110Datas();
		        if(lotStep110Datas != null && lotStep110Datas.size() > 0)
		        	this.initLotProperties(step110Data, lotStep110Datas.toArray()[0], this.getLotSynProperties(step110Data));
	        }
	        
	        if(template.getSteps().contains("step120_1")){
		        Step120_1Data step120_1Data = new Step120_1Data();
		        step120_1Data.setProduct(product);
		        product.setStep120_1Datas(new HashSet<Step120_1Data>());
		        product.getStep120_1Datas().add(step120_1Data);
		        Set<Step120_1Data> lotStep120_1Datas = null == lotProduct? null : lotProduct.getStep120_1Datas();
		        if(lotStep120_1Datas != null && lotStep120_1Datas.size() > 0)
		        	this.initLotProperties(step120_1Data, lotStep120_1Datas.toArray()[0], this.getLotSynProperties(step120_1Data));
	        }
	        
	        if(template.getSteps().contains("step120_2")){
		        Step120_2Data step120_2Data = new Step120_2Data();
		        step120_2Data.setProduct(product);
		        product.setStep120_2Datas(new HashSet<Step120_2Data>());
		        product.getStep120_2Datas().add(step120_2Data);
		        Set<Step120_2Data> lotStep120_2Datas = null == lotProduct? null : lotProduct.getStep120_2Datas();
		        if(lotStep120_2Datas != null && lotStep120_2Datas.size() > 0)
		        	this.initLotProperties(step120_2Data, lotStep120_2Datas.toArray()[0], this.getLotSynProperties(step120_2Data));
	        }
	        
	        if(template.getSteps().contains("step130")){
		        Step130Data step130Data = new Step130Data();
		        step130Data.setProduct(product);
		        product.setStep130Datas(new HashSet<Step130Data>());
		        product.getStep130Datas().add(step130Data);
		        Set<Step130Data> lotStep130Datas = null == lotProduct? null : lotProduct.getStep130Datas();
		        if(lotStep130Datas != null && lotStep130Datas.size() > 0)
		        	this.initLotProperties(step130Data, lotStep130Datas.toArray()[0], this.getLotSynProperties(step130Data));
	        }
	        
	        if(template.getSteps().contains("step140_1")){
		        Step140_1Data step140_1Data = new Step140_1Data();
		        step140_1Data.setProduct(product);
		        product.setStep140_1Datas(new HashSet<Step140_1Data>());
		        product.getStep140_1Datas().add(step140_1Data);
		        Set<Step140_1Data> lotStep140_1Datas = null == lotProduct? null : lotProduct.getStep140_1Datas();
		        if(lotStep140_1Datas != null && lotStep140_1Datas.size() > 0)
		        	this.initLotProperties(step140_1Data, lotStep140_1Datas.toArray()[0], this.getLotSynProperties(step140_1Data));
	        }
	        
	        if(template.getSteps().contains("step140_2")){
		        Step140_2Data step140_2Data = new Step140_2Data();
		        step140_2Data.setProduct(product);
		        product.setStep140_2Datas(new HashSet<Step140_2Data>());
		        product.getStep140_2Datas().add(step140_2Data);
		        Set<Step140_2Data> lotStep140_2Datas = null == lotProduct? null : lotProduct.getStep140_2Datas();
		        if(lotStep140_2Datas != null && lotStep140_2Datas.size() > 0)
		        	this.initLotProperties(step140_2Data, lotStep140_2Datas.toArray()[0], this.getLotSynProperties(step140_2Data));
	        }
	        
	        if(template.getSteps().contains("step150")){
		        Step150Data step150Data = new Step150Data();
		        step150Data.setProduct(product);
		        product.setStep150Datas(new HashSet<Step150Data>());
		        product.getStep150Datas().add(step150Data);
		        Set<Step150Data> lotStep150Datas = null == lotProduct? null : lotProduct.getStep150Datas();
		        if(lotStep150Datas != null && lotStep150Datas.size() > 0)
		        	this.initLotProperties(step150Data, lotStep150Datas.toArray()[0], this.getLotSynProperties(step150Data));
	        }
	        
	        if(template.getSteps().contains("step160")){
		        Step160Data step160Data = new Step160Data();
		        step160Data.setProduct(product);
		        product.setStep160Datas(new HashSet<Step160Data>());
		        product.getStep160Datas().add(step160Data);
		        Set<Step160Data> lotStep160Datas = null == lotProduct? null : lotProduct.getStep160Datas();
		        if(lotStep160Datas != null && lotStep160Datas.size() > 0)
		        	this.initLotProperties(step160Data, lotStep160Datas.toArray()[0], this.getLotSynProperties(step160Data));
	        }
	        
	        if(template.getSteps().contains("step170_1")){
		        Step170_1Data step170_1Data = new Step170_1Data();
		        step170_1Data.setProduct(product);
		        product.setStep170_1Datas(new HashSet<Step170_1Data>());
		        product.getStep170_1Datas().add(step170_1Data);
		        Set<Step170_1Data> lotStep170_1Datas = null == lotProduct? null : lotProduct.getStep170_1Datas();
		        if(lotStep170_1Datas != null && lotStep170_1Datas.size() > 0)
		        	this.initLotProperties(step170_1Data, lotStep170_1Datas.toArray()[0], this.getLotSynProperties(step170_1Data));
	        }
	        
	        if(template.getSteps().contains("step170_2")){
		        Step170_2Data step170_2Data = new Step170_2Data();
		        step170_2Data.setProduct(product);
		        product.setStep170_2Datas(new HashSet<Step170_2Data>());
		        product.getStep170_2Datas().add(step170_2Data);
		        Set<Step170_2Data> lotStep170_2Datas = null == lotProduct? null : lotProduct.getStep170_2Datas();
		        if(lotStep170_2Datas != null && lotStep170_2Datas.size() > 0)
		        	this.initLotProperties(step170_2Data, lotStep170_2Datas.toArray()[0], this.getLotSynProperties(step170_2Data));
	        }
	        
	        if(template.getSteps().contains("step180")){
		        Step180Data step180Data = new Step180Data();
		        step180Data.setProduct(product);
		        product.setStep180Datas(new HashSet<Step180Data>());
		        product.getStep180Datas().add(step180Data);
		        Set<Step180Data> lotStep180Datas = null == lotProduct? null : lotProduct.getStep180Datas();
		        if(lotStep180Datas != null && lotStep180Datas.size() > 0)
		        	this.initLotProperties(step180Data, lotStep180Datas.toArray()[0], this.getLotSynProperties(step180Data));
	        }
	        
	        DataSheet dataSheet = new DataSheet();
	        dataSheet.setProduct(product);
	        product.setDataSheet(dataSheet);
	        
	        if(!dumy){
		        this.productDao.save(product);
		        if(this.isAutoCreateSn())
		        	this.productDao.updateSn(product.getId(), this.createSn(product.getId()));
	        }
		}
        return current;
	}
	
	public Product getProduct(Long id){
		Product product = this.productDao.loadAll(id);
		if(product.getStepSpecId() != null){
			product.setStepSpec(this.stepSpecDao.get(product.getStepSpecId()));
		}
		return product;
	}
	
	public Product getProductMeta(Long id){
		Product product = this.productDao.get(id);
		return product;
	}
	
	public Product getProductByProcess(String processInstanceId){
		return this.productDao.getProductByProcess(processInstanceId);
	}
	
	public void deleteProduct(Long productId){
		Product product = this.getProduct(productId);
		ExecutionService executionService = processEngine.getExecutionService();
		executionService.deleteProcessInstance(product.getProcessId());
		this.productDao.deleteByKey(productId);
	}
	
	public Set<String> findActiveActivityNames(String processInstanceId){
		ExecutionService executionService = processEngine.getExecutionService();
		Execution execution = executionService.findExecutionById(processInstanceId);
		return execution.findActiveActivityNames();
	}
	
	public String[] findFailedCells(String processId){
		ExecutionService executionService = processEngine.getExecutionService();
		Object obj = executionService.getVariable(processId, "failedCells");
		String[] cells = null==obj?new String[]{}:(String[])obj;
		return cells;
	}

	public void saveData(Object obj, boolean submit, String testResult){
		Employee user = this.userService.getCurrentUser();
		if(obj instanceof Product){
			Product product = (Product)obj;
			Set<String> status = this.findActiveActivityNames(product.getProcessId());
			product.setStatus(status.toArray()[0].toString());
			this.productDao.saveOrUpdate(product);
			this.productDao.synLotProperties(product, this.getLotSynProperties(obj));
			DataSheet dataSheet = this.dataSheetDao.getDataSheetByProduct(product.getId());
			if(product.getFinalSn() != null)
				dataSheet.setSn(product.getFinalSn());
			if(product.getPn() != null)
				dataSheet.setInternalPn(product.getPn());
			if(product.getItuch() != null)
				dataSheet.setItuChannel(product.getItuch());
			if(product.getChannelPb2() != null)
				dataSheet.setChannelPassband(product.getChannelPb2());
			this.dataSheetDao.saveOrUpdate(dataSheet);
		}else if(obj instanceof Step10_1Data){
			Step10_1Data step = (Step10_1Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step10_1DataDao.saveOrUpdate(step);
			this.step10_1DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step10_2Data){
			Step10_2Data step = (Step10_2Data)obj;
			if(testResult != null)
				step.setTestResult(testResult);
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step10_2DataDao.saveOrUpdate(step);
			this.step10_2DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step20Data){
			Step20Data step = (Step20Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step20DataDao.saveOrUpdate(step);
			this.step20DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step30_1Data){
			Step30_1Data step = (Step30_1Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step30_1DataDao.saveOrUpdate(step);
			this.step30_1DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step30_2Data){
			Step30_2Data step = (Step30_2Data)obj;
			if(testResult != null)
				step.setTestResult(testResult);
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step30_2DataDao.saveOrUpdate(step);
			this.step30_2DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step40Data){
			Step40Data step = (Step40Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step40DataDao.saveOrUpdate(step);
			this.step40DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step50Data){
			Step50Data step = (Step50Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step50DataDao.saveOrUpdate(step);
			this.step50DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step60Data){
			Step60Data step = (Step60Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step60DataDao.saveOrUpdate(step);
			this.step60DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step70Data){
			Step70Data step = (Step70Data)obj;
			this.step70DataDao.saveOrUpdate(step);
			this.step70DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}
		else if(obj instanceof Step80Data){
			Step80Data step = (Step80Data)obj;
			if(testResult != null)
				step.setTestResult(testResult);
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step80DataDao.saveOrUpdate(step);
			this.step80DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step90Data){
			Step90Data step = (Step90Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step90DataDao.saveOrUpdate(step);
			this.step90DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step100_1Data){
			Step100_1Data step = (Step100_1Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step100_1DataDao.saveOrUpdate(step);
			this.step100_1DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step100_2Data){
			Step100_2Data step = (Step100_2Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step100_2DataDao.saveOrUpdate(step);
			this.step100_2DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step100_3Data){
			Step100_3Data step = (Step100_3Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step100_3DataDao.saveOrUpdate(step);
			this.step100_3DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step110Data){
			Step110Data step = (Step110Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			if(submit && isRework()){
				Step110DataRemark remark =  new Step110DataRemark();
				remark.setDate((Date)step.getDate().clone());
				remark.setOperator(new String(step.getOperator()));
				remark.setRemark(new String(step.getRemark()));
				remark.setTestResult(new String(step.getTestResult()));
				remark.setStep110Data(step);
				if(step.getRemarkLogs() == null)
					step.setRemarkLogs(new HashSet<Step110DataRemark>());
				step.getRemarkLogs().add(remark);
				step.setDate(null);
				step.setOperator(null);
				step.setRemark(null);
				step.setTestResult(null);
			}
			this.step110DataDao.saveOrUpdate(step);
			this.step110DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step120_1Data){
			Step120_1Data step = (Step120_1Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step120_1DataDao.saveOrUpdate(step);
			this.step120_1DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step120_2Data){
			Step120_2Data step = (Step120_2Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step120_2DataDao.saveOrUpdate(step);
			this.step120_2DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step130Data){
			Step130Data step = (Step130Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			if(submit && isRework()){
				Step130DataRemark remark =  new Step130DataRemark();
				remark.setDate((Date)step.getDate().clone());
				remark.setOperator(new String(step.getOperator()));
				remark.setRemark(new String(step.getRemark()));
				remark.setTestResult(new String(step.getTestResult()));
				remark.setStep130Data(step);
				if(step.getRemarkLogs() == null)
					step.setRemarkLogs(new HashSet<Step130DataRemark>());
				step.getRemarkLogs().add(remark);
				step.setDate(null);
				step.setOperator(null);
				step.setRemark(null);
				step.setTestResult(null);
			}
			this.step130DataDao.saveOrUpdate(step);
			this.step130DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step140_1Data){
			Step140_1Data step = (Step140_1Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step140_1DataDao.saveOrUpdate(step);
			this.step140_1DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
			this.calculateStep140_1(step);
		}else if(obj instanceof Step140_2Data){
			Step140_2Data step = (Step140_2Data)obj;
			if(testResult != null)
				step.setTestResult(testResult);
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step140_2DataDao.saveOrUpdate(step);
			this.step140_2DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
			this.calculateStep140_2(step);
		}else if(obj instanceof Step150Data){
			Step150Data step = (Step150Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step150DataDao.saveOrUpdate(step);
			this.step150DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step160Data){
			Step160Data step = (Step160Data)obj;
			if(testResult != null)
				step.setTestResult(testResult);
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step160DataDao.saveOrUpdate(step);
			this.step160DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step170_1Data){
			Step170_1Data step = (Step170_1Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step170_1DataDao.saveOrUpdate(step);
			this.step170_1DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step170_2Data){
			Step170_2Data step = (Step170_2Data)obj;
			if(testResult != null)
				step.setTestResult(testResult);
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step170_2DataDao.saveOrUpdate(step);
			this.step170_2DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof Step180Data){
			Step180Data step = (Step180Data)obj;
			if(step.getOperator() == null)
				step.setOperator(user.getUsername());
			if(step.getDate() == null)
				step.setDate(new Date());
			this.step180DataDao.saveOrUpdate(step);
			this.step180DataDao.synLotProperties(step.getProduct().getId(), obj, this.getLotSynProperties(obj));
		}else if(obj instanceof DataSheet){
			DataSheet dataSheet = (DataSheet)obj;
			dataSheet.setDate(new Date());
			this.dataSheetDao.saveOrUpdate(dataSheet);
			Product product = this.getProduct(dataSheet.getProduct().getId());
			if(dataSheet.getSn() != null)
				product.setFinalSn(dataSheet.getSn());
			if(dataSheet.getItuChannel() != null)
				product.setItuch(dataSheet.getItuChannel());
			if(dataSheet.getChannelPassband() != null)
				product.setChannelPb2(dataSheet.getChannelPassband());
			this.productDao.saveOrUpdate(product);
		}
	}
	
	private void calculateStep140_1(Step140_1Data step){
		DataSheet dataSheet = this.dataSheetDao.getDataSheetByProduct(step.getProduct().getId());
		//Calculate IL max
		Double pil = null;
		if(step.getIlParm1() != null && step.getIlParm1().trim().length() > 0){
			Double il = new Double(step.getIlParm1());
			pil = il;
		}
		if(step.getIlParm2() != null && step.getIlParm2().trim().length() > 0){
			Double il2 = new Double(step.getIlParm2());
			if(pil == null)
				pil = il2;
			else
				pil = pil<il2?il2:pil;
		}
		if(step.getIlParm3() != null && step.getIlParm3().trim().length() > 0){
			Double il3 = new Double(step.getIlParm3());
			if(pil == null)
				pil = il3;
			else
				pil = pil<il3?il3:pil;
		}
		if(pil != null)
			dataSheet.setPassbandInsertionLoss(String.valueOf(pil));
		//Calculate Ripple max
		Double pr = null;
		if(step.getRippleParm1() != null && step.getRippleParm1().trim().length() > 0){
			Double r = new Double(step.getRippleParm1());
			pr = r;
		}
		if(step.getRippleParm2() != null && step.getRippleParm2().trim().length() > 0){
			Double r2 = new Double(step.getRippleParm2());
			if(pr == null)
				pr = r2;
			else
				pr = pr<r2?r2:pr;
		}
		if(step.getRippleParm3() != null && step.getRippleParm3().trim().length() > 0){
			Double r3 = new Double(step.getRippleParm3());
			if(pr == null)
				pr = r3;
			else
				pr = pr<r3?r3:pr;
		}
		if(pr != null)
			dataSheet.setPassbandRipple(String.valueOf(pr));
		//Calculate ISO-L/ISO-R min
		Double ac = null;
		if(step.getIsolParm1() != null && step.getIsolParm1().trim().length() > 0){
			Double isol = new Double(step.getIsolParm1());
			ac = isol;
		}
		if(step.getIsolParm2() != null && step.getIsolParm2().trim().length() > 0){
			Double isol2 = new Double(step.getIsolParm2());
			if(ac == null)
				ac = isol2;
			else
				ac = ac>isol2?isol2:ac;
		}
		if(step.getIsolParm3() != null && step.getIsolParm3().trim().length() > 0){
			Double isol3 = new Double(step.getIsolParm3());
			if(ac == null)
				ac = isol3;
			else
				ac = ac>isol3?isol3:ac;
		}
		if(step.getIsorParm1() != null && step.getIsorParm1().trim().length() > 0){
			Double isor = new Double(step.getIsorParm1());
			if(ac == null)
				ac = isor;
			else
				ac = ac>isor?isor:ac;
		}
		if(step.getIsorParm2() != null && step.getIsorParm2().trim().length() > 0){
			Double isor2 = new Double(step.getIsorParm2());
			if(ac == null)
				ac = isor2;
			else
				ac = ac>isor2?isor2:ac;
		}
		if(step.getIsorParm3() != null && step.getIsorParm3().trim().length() > 0){
			Double isor3 = new Double(step.getIsorParm3());
			if(ac == null)
				ac = isor3;
			else
				ac = ac>isor3?isor3:ac;
		}
		if(ac != null)
			dataSheet.setIsolationAdjacentChannel(String.valueOf(ac));
		//Calculate N-ISO-L/N-ISO-R min
		Double nac = null;
		if(step.getNisolParm1() != null && step.getNisolParm1().trim().length() > 0){
			Double nisol = new Double(step.getNisolParm1());
			nac = nisol;
		}
		if(step.getNisolParm2() != null && step.getNisolParm2().trim().length() > 0){
			Double nisol2 = new Double(step.getNisolParm2());
			if(nac == null)
				nac = nisol2;
			else
				nac = nac>nisol2?nisol2:nac;
		}
		if(step.getNisolParm3() != null && step.getNisolParm3().trim().length() > 0){
			Double nisol3 = new Double(step.getNisolParm3());
			if(nac == null)
				nac = nisol3;
			else
				nac = nac>nisol3?nisol3:nac;
		}
		if(step.getNisorParm1() != null && step.getNisorParm1().trim().length() > 0){
			Double nisor = new Double(step.getNisorParm1());
			if(nac == null)
				nac = nisor;
			else
				nac = nac>nisor?nisor:nac;
		}
		if(step.getNisorParm2() != null && step.getNisorParm2().trim().length() > 0){
			Double nisor2 = new Double(step.getNisorParm2());
			if(nac == null)
				nac = nisor2;
			else
				nac = nac>nisor2?nisor2:nac;
		}
		if(step.getNisorParm3() != null && step.getNisorParm3().trim().length() > 0){
			Double nisor3 = new Double(step.getNisorParm3());
			if(nac == null)
				nac = nisor3;
			else
				nac = nac>nisor3?nisor3:nac;
		}
		if(nac != null)
			dataSheet.setIsolationNonAdjacentChannel(String.valueOf(nac));
		//Calculate R IL-l/R IL-R max
		Double ril = null;
		if(step.getRillParm1() != null && step.getRillParm1().trim().length() > 0){
			Double rill = new Double(step.getRillParm1());
			ril = rill;
		}
		if(step.getRillParm2() != null && step.getRillParm2().trim().length() > 0){
			Double rill2 = new Double(step.getRillParm2());
			if(ril == null)
				ril = rill2;
			else
				ril = ril<rill2?rill2:ril;
		}
		if(step.getRillParm3() != null && step.getRillParm3().trim().length() > 0){
			Double rill3 = new Double(step.getRillParm3());
			if(ril == null)
				ril = rill3;
			else
				ril = ril<rill3?rill3:ril;
		}
		if(step.getRilrParm1() != null && step.getRilrParm1().trim().length() > 0){
			Double rilr = new Double(step.getRilrParm1());
			if(ril == null)
				ril = rilr;
			else
				ril = ril<rilr?rilr:ril;
		}
		if(step.getRilrParm2() != null && step.getRilrParm2().trim().length() > 0){
			Double rilr2 = new Double(step.getRilrParm2());
			if(ril == null)
				ril = rilr2;
			else
				ril = ril<rilr2?rilr2:ril;
		}
		if(step.getRilrParm3() != null && step.getRilrParm3().trim().length() > 0){
			Double rilr3 = new Double(step.getRilrParm3());
			if(ril == null)
				ril = rilr3;
			else
				ril = ril<rilr3?rilr3:ril;
		}
		if(ril != null)
			dataSheet.setReflectedInsertionLoss(String.valueOf(ril));
		//Calculate Ripple-l/Ripple-r max
		Double rr = null;
		if(step.getRipplelParm1() != null && step.getRipplelParm1().trim().length() > 0){
			Double rlp = new Double(step.getRipplelParm1());
			rr = rlp;
		}
		if(step.getRipplelParm2() != null && step.getRipplelParm2().trim().length() > 0){
			Double rlp2 = new Double(step.getRipplelParm2());
			if(rr == null)
				rr = rlp2;
			else
				rr = rr<rlp2?rlp2:rr;
		}
		if(step.getRipplelParm3() != null && step.getRipplelParm3().trim().length() > 0){
			Double rlp3 = new Double(step.getRipplelParm3());
			if(rr == null)
				rr = rlp3;
			else
				rr = rr<rlp3?rlp3:rr;
		}
		if(step.getRipplerParm1() != null && step.getRipplerParm1().trim().length() > 0){
			Double rrp = new Double(step.getRipplerParm1());
			if(rr == null)
				rr = rrp;
			else
				rr = rr<rrp?rrp:rr;
		}
		if(step.getRipplerParm2() != null && step.getRipplerParm2().trim().length() > 0){
			Double rrp2 = new Double(step.getRipplerParm2());
			if(rr == null)
				rr = rrp2;
			else
				rr = rr<rrp2?rrp2:rr;
		}
		if(step.getRipplerParm3() != null && step.getRipplerParm3().trim().length() > 0){
			Double rrp3 = new Double(step.getRipplerParm3());
			if(rr == null)
				rr = rrp3;
			else
				rr = rr<rrp3?rrp3:rr;
		}
		if(rr != null)
			dataSheet.setReflectedRipple(String.valueOf(rr));
		//Calculate Min-R-ISO min
		Double ri = null;
		if(step.getMinRisoParm1() != null && step.getMinRisoParm1().trim().length() > 0){
			Double mr = new Double(step.getMinRisoParm1());
			ri = mr;
		}
		if(step.getMinRisoParm2() != null && step.getMinRisoParm2().trim().length() > 0){
			Double mr2 = new Double(step.getMinRisoParm2());
			if(ri == null)
				ri = mr2;
			else
				ri = ri>mr2?mr2:ri;
		}
		if(step.getMinRisoParm3() != null && step.getMinRisoParm3().trim().length() > 0){
			Double mr3 = new Double(step.getMinRisoParm3());
			if(ri == null)
				ri = mr3;
			else
				ri = ri>mr3?mr3:ri;
		}
		if(ri != null)
			dataSheet.setReflectedIsolation(String.valueOf(ri));
		//Calculate PDL-PB/PDL-ITU/PDL+PB max
		Double pdl = null;
		if(step.getPdlPb2Parm1() != null && step.getPdlPb2Parm1().trim().length() > 0){
			Double pp = new Double(step.getPdlPb2Parm1());
			pdl = pp;
		}
		if(step.getPdlPb2Parm2() != null && step.getPdlPb2Parm2().trim().length() > 0){
			Double pp2 = new Double(step.getPdlPb2Parm2());
			if(pdl == null)
				pdl = pp2;
			else
				pdl = pdl<pp2?pp2:pdl;
		}
		if(step.getPdlPb2Parm3() != null && step.getPdlPb2Parm3().trim().length() > 0){
			Double pp3 = new Double(step.getPdlPb2Parm3());
			if(pdl == null)
				pdl = pp3;
			else
				pdl = pdl<pp3?pp3:pdl;
		}
		if(step.getPdlItuParm1() != null && step.getPdlItuParm1().trim().length() > 0){
			Double pi = new Double(step.getPdlItuParm1());
			if(pdl == null)
				pdl = pi;
			else
				pdl = pdl<pi?pi:pdl;
		}
		if(step.getPdlItuParm2() != null && step.getPdlItuParm2().trim().length() > 0){
			Double pi2 = new Double(step.getPdlItuParm2());
			if(pdl == null)
				pdl = pi2;
			else
				pdl = pdl<pi2?pi2:pdl;
		}
		if(step.getPdlItuParm3() != null && step.getPdlItuParm3().trim().length() > 0){
			Double pi3 = new Double(step.getPdlItuParm3());
			if(pdl == null)
				pdl = pi3;
			else
				pdl = pdl<pi3?pi3:pdl;
		}
		if(step.getPdlaPb2Parm1() != null && step.getPdlaPb2Parm1().trim().length() > 0){
			Double pap = new Double(step.getPdlaPb2Parm1());
			if(pdl == null)
				pdl = pap;
			else
				pdl = pdl<pap?pap:pdl;
		}
		if(step.getPdlaPb2Parm2() != null && step.getPdlaPb2Parm2().trim().length() > 0){
			Double pap2 = new Double(step.getPdlaPb2Parm2());
			if(pdl == null)
				pdl = pap2;
			else
				pdl = pdl<pap2?pap2:pdl;
		}
		if(step.getPdlaPb2Parm3() != null && step.getPdlaPb2Parm3().trim().length() > 0){
			Double pap3 = new Double(step.getPdlaPb2Parm3());
			if(pdl == null)
				pdl = pap3;
			else
				pdl = pdl<pap3?pap3:pdl;
		}
		if(pdl != null)
			dataSheet.setPdl(String.valueOf(pdl));
		
		this.dataSheetDao.saveOrUpdate(dataSheet);
	}
	
	private void calculateStep140_2(Step140_2Data step){
		DataSheet dataSheet = this.dataSheetDao.getDataSheetByProduct(step.getProduct().getId());
		//Calculate RL min
		Double rl = null;
		if(step.getRlRportParm1() != null && step.getRlRportParm1().trim().length() > 0){
			Double rlr = new Double(step.getRlRportParm1());
			rl = rlr;
		}
		if(step.getRlPportParm2() != null && step.getRlPportParm2().trim().length() > 0){
			Double rlr2 = new Double(step.getRlPportParm2());
			if(rl == null)
				rl = rlr2;
			else
				rl = rl>rlr2?rlr2:rl;
		}
		if(step.getRlRportParm3() != null && step.getRlRportParm3().trim().length() > 0){
			Double rlr3 = new Double(step.getRlRportParm3());
			if(rl == null)
				rl = rlr3;
			else
				rl = rl>rlr3?rlr3:rl;
		}
		if(step.getRlCportParm1() != null && step.getRlCportParm1().trim().length() > 0){
			Double rlc = new Double(step.getRlCportParm1());
			if(rl == null)
				rl = rlc;
			else
				rl = rl>rlc?rlc:rl;
		}
		if(step.getRlCportParm2() != null && step.getRlCportParm2().trim().length() > 0){
			Double rlc2 = new Double(step.getRlCportParm2());
			if(rl == null)
				rl = rlc2;
			else
				rl = rl>rlc2?rlc2:rl;
		}
		if(step.getRlCportParm3() != null && step.getRlCportParm3().trim().length() > 0){
			Double rlc3 = new Double(step.getRlCportParm3());
			if(rl == null)
				rl = rlc3;
			else
				rl = rl>rlc3?rlc3:rl;
		}
		if(rl != null)
			dataSheet.setReturnLoss(String.valueOf(rl));
		//Calculate DIR min
		Double dir = null;
		if(step.getDirRpParm1() != null && step.getDirRpParm1().trim().length() > 0){
			Double rp = new Double(step.getDirRpParm1());
			dir = rp;
		}
		if(step.getDirPrParm2() != null && step.getDirPrParm2().trim().length() > 0){
			Double pr2 = new Double(step.getDirPrParm2());
			if(dir == null)
				dir = pr2;
			else
				dir = dir>pr2?pr2:dir;
		}
		if(step.getDirRpParm3() != null && step.getDirRpParm3().trim().length() > 0){
			Double rp3 = new Double(step.getDirRpParm3());
			if(dir == null)
				dir = rp3;
			else
				dir = dir>rp3?rp3:dir;
		}
		if(dir != null)
			dataSheet.setDirectivity(String.valueOf(dir));
		
		this.dataSheetDao.saveOrUpdate(dataSheet);
	}
	
	public String signal(String processId, String step, Map<String, ?> map){
		ExecutionService executionService = processEngine.getExecutionService();
		ProcessInstance processInstance = executionService.findProcessInstanceById(processId);
		Execution exec = processInstance.findActiveExecutionIn(step);
		if(map == null){
			executionService.signalExecutionById(exec.getId());
			return null;
		}else{
			executionService.signalExecutionById(exec.getId(), map);
			return map.get(StepActionUtil.TESTRESULT).toString();
		}
	}
	
	public void saveDataAndSignal(Object obj, Long productId, String step, Map<String, ?> map){
		Product product = this.getProduct(productId);
		this.saveData(obj, true, null);
		String testResult = this.signal(product.getProcessId(), step, map);
		this.saveData(obj, true, testResult);
		Set<String> set = this.findActiveActivityNames(product.getProcessId());
		String status = set.toArray()[0].toString();
		if(testResult != null && (testResult.equals(StepActionUtil.TESTRESULT_FAILURE) || testResult.equals(StepActionUtil.TESTRESULT_WAIVE)))
			status = StepActionUtil.toWaiveFail(status, testResult);
		this.productDao.updateStatus(productId, status);
	}
	
	public List<Template> getAllTemplates(){
		return this.templateDao.loadAll();
	}
	
	public Template getTemplate(Long id){
		return this.templateDao.get(id);
	}
	
	public void createTemplate(Template template){
		this.templateDao.save(template);
	}
	
	public void updateTemplate(Template template){
		this.templateDao.saveOrUpdate(template);
	}
	
    public void deleteTemplate(Long templateId) {
    	this.templateDao.deleteByKey(templateId);
    }
    
	public List<StepSpec> getAllStepSpecs(){
		return this.stepSpecDao.loadAll();
	}
    
	public StepSpec getStepSpec(Long id){
		StepSpec spec = this.stepSpecDao.get(id);
		if(spec == null)
			return null;
		spec.setStep10_1Data(null==spec.getStep10_1DataId()?null:this.step10_1DataDao.get(spec.getStep10_1DataId()));
		spec.setStep10_1Operation(null==spec.getStep10_1OperationId()?null:this.step10_1DataDao.get(spec.getStep10_1OperationId()));
		spec.setStep10_2Data(null==spec.getStep10_2DataId()?null:this.step10_2DataDao.get(spec.getStep10_2DataId()));
		spec.setStep10_2Operation(null==spec.getStep10_2OperationId()?null:this.step10_2DataDao.get(spec.getStep10_2OperationId()));
		spec.setStep30_2Data(null==spec.getStep30_2DataId()?null:this.step30_2DataDao.get(spec.getStep30_2DataId()));
		spec.setStep30_2Operation(null==spec.getStep30_2OperationId()?null:this.step30_2DataDao.get(spec.getStep30_2OperationId()));
		spec.setStep80Data(null==spec.getStep80DataId()?null:this.step80DataDao.get(spec.getStep80DataId()));
		spec.setStep80Operation(null==spec.getStep80OperationId()?null:this.step80DataDao.get(spec.getStep80OperationId()));
		spec.setStep140_1Data(null==spec.getStep140_1DataId()?null:this.step140_1DataDao.get(spec.getStep140_1DataId()));
		spec.setStep140_1Operation(null==spec.getStep140_1OperationId()?null:this.step140_1DataDao.get(spec.getStep140_1OperationId()));
		spec.setStep140_2Data(null==spec.getStep140_2DataId()?null:this.step140_2DataDao.get(spec.getStep140_2DataId()));
		spec.setStep140_2Operation(null==spec.getStep140_2OperationId()?null:this.step140_2DataDao.get(spec.getStep140_2OperationId()));
		spec.setStep160Data(null==spec.getStep160DataId()?null:this.step160DataDao.get(spec.getStep160DataId()));
		spec.setStep160Operation(null==spec.getStep160OperationId()?null:this.step160DataDao.get(spec.getStep160OperationId()));
		spec.setStep170_1Data(null==spec.getStep170_1DataId()?null:this.step170_1DataDao.get(spec.getStep170_1DataId()));
		spec.setStep170_1Operation(null==spec.getStep170_1OperationId()?null:this.step170_1DataDao.get(spec.getStep170_1OperationId()));
		spec.setStep170_2Data(null==spec.getStep170_2DataId()?null:this.step170_2DataDao.get(spec.getStep170_2DataId()));
		spec.setStep170_2Operation(null==spec.getStep170_2OperationId()?null:this.step170_2DataDao.get(spec.getStep170_2OperationId()));
		return spec;
	}
	
	public void createStepSpec(StepSpec stepSpec){
		Product product = new Product();
		product.setId(new Long(-1));
		
		if(stepSpec.getStep10_1Data()!= null && stepSpec.getStep10_1Operation() != null){
			stepSpec.getStep10_1Data().setProduct(product);
			stepSpec.getStep10_1Operation().setProduct(product);
			this.step10_1DataDao.save(stepSpec.getStep10_1Data());
			this.step10_1DataDao.save(stepSpec.getStep10_1Operation());
			stepSpec.setStep10_1DataId(stepSpec.getStep10_1Data().getId());
			stepSpec.setStep10_1OperationId(stepSpec.getStep10_1Operation().getId());
		}
		
		if(stepSpec.getStep10_2Data()!= null && stepSpec.getStep10_2Operation() != null){
			stepSpec.getStep10_2Data().setProduct(product);
			stepSpec.getStep10_2Operation().setProduct(product);
			this.step10_2DataDao.save(stepSpec.getStep10_2Data());
			this.step10_2DataDao.save(stepSpec.getStep10_2Operation());
			stepSpec.setStep10_2DataId(stepSpec.getStep10_2Data().getId());
			stepSpec.setStep10_2OperationId(stepSpec.getStep10_2Operation().getId());
		}
		
		if(stepSpec.getStep30_2Data()!= null && stepSpec.getStep30_2Operation() != null){
			stepSpec.getStep30_2Data().setProduct(product);
			stepSpec.getStep30_2Operation().setProduct(product);
			this.step30_2DataDao.save(stepSpec.getStep30_2Data());
			this.step30_2DataDao.save(stepSpec.getStep30_2Operation());
			stepSpec.setStep30_2DataId(stepSpec.getStep30_2Data().getId());
			stepSpec.setStep30_2OperationId(stepSpec.getStep30_2Operation().getId());
		}
		
		if(stepSpec.getStep80Data()!= null && stepSpec.getStep80Operation() != null){
			stepSpec.getStep80Data().setProduct(product);
			stepSpec.getStep80Operation().setProduct(product);
			this.step80DataDao.save(stepSpec.getStep80Data());
			this.step80DataDao.save(stepSpec.getStep80Operation());
			stepSpec.setStep80DataId(stepSpec.getStep80Data().getId());
			stepSpec.setStep80OperationId(stepSpec.getStep80Operation().getId());
		}
		
		if(stepSpec.getStep140_1Data()!= null && stepSpec.getStep140_1Operation() != null){
			stepSpec.getStep140_1Data().setProduct(product);
			stepSpec.getStep140_1Operation().setProduct(product);
			this.step140_1DataDao.save(stepSpec.getStep140_1Data());
			this.step140_1DataDao.save(stepSpec.getStep140_1Operation());
			stepSpec.setStep140_1DataId(stepSpec.getStep140_1Data().getId());
			stepSpec.setStep140_1OperationId(stepSpec.getStep140_1Operation().getId());
		}
		
		if(stepSpec.getStep140_2Data()!= null && stepSpec.getStep140_2Operation() != null){
			stepSpec.getStep140_2Data().setProduct(product);
			stepSpec.getStep140_2Operation().setProduct(product);
			this.step140_2DataDao.save(stepSpec.getStep140_2Data());
			this.step140_2DataDao.save(stepSpec.getStep140_2Operation());
			stepSpec.setStep140_2DataId(stepSpec.getStep140_2Data().getId());
			stepSpec.setStep140_2OperationId(stepSpec.getStep140_2Operation().getId());
		}
		
		if(stepSpec.getStep160Data()!= null && stepSpec.getStep160Operation() != null){
			stepSpec.getStep160Data().setProduct(product);
			stepSpec.getStep160Operation().setProduct(product);
			this.step160DataDao.save(stepSpec.getStep160Data());
			this.step160DataDao.save(stepSpec.getStep160Operation());
			stepSpec.setStep160DataId(stepSpec.getStep160Data().getId());
			stepSpec.setStep160OperationId(stepSpec.getStep160Operation().getId());
		}
		
		if(stepSpec.getStep170_1Data()!= null && stepSpec.getStep170_1Operation() != null){
			stepSpec.getStep170_1Data().setProduct(product);
			stepSpec.getStep170_1Operation().setProduct(product);
			this.step170_1DataDao.save(stepSpec.getStep170_1Data());
			this.step170_1DataDao.save(stepSpec.getStep170_1Operation());
			stepSpec.setStep170_1DataId(stepSpec.getStep170_1Data().getId());
			stepSpec.setStep170_1OperationId(stepSpec.getStep170_1Operation().getId());
		}
		
		if(stepSpec.getStep170_2Data()!= null && stepSpec.getStep170_2Operation() != null){
			stepSpec.getStep170_2Data().setProduct(product);
			stepSpec.getStep170_2Operation().setProduct(product);
			this.step170_2DataDao.save(stepSpec.getStep170_2Data());
			this.step170_2DataDao.save(stepSpec.getStep170_2Operation());
			stepSpec.setStep170_2DataId(stepSpec.getStep170_2Data().getId());
			stepSpec.setStep170_2OperationId(stepSpec.getStep170_2Operation().getId());
		}
		this.stepSpecDao.save(stepSpec);
	}
	
	public void updateStepSpec(StepSpec stepSpec){
		this.stepSpecDao.saveOrUpdate(stepSpec);
		if(stepSpec.getStep10_1Data()!= null && stepSpec.getStep10_1Operation() != null){
			stepSpec.getStep10_1Data().setId(stepSpec.getStep10_1DataId());
			stepSpec.getStep10_1Operation().setId(stepSpec.getStep10_1OperationId());
			this.step10_1DataDao.saveOrUpdate(stepSpec.getStep10_1Data());
			this.step10_1DataDao.saveOrUpdate(stepSpec.getStep10_1Operation());
		}
		
		if(stepSpec.getStep10_2Data()!= null && stepSpec.getStep10_2Operation() != null){
			stepSpec.getStep10_2Data().setId(stepSpec.getStep10_2DataId());
			stepSpec.getStep10_2Operation().setId(stepSpec.getStep10_2OperationId());
			this.step10_2DataDao.saveOrUpdate(stepSpec.getStep10_2Data());
			this.step10_2DataDao.saveOrUpdate(stepSpec.getStep10_2Operation());
		}
		
		if(stepSpec.getStep30_2Data()!= null && stepSpec.getStep30_2Operation() != null){
			stepSpec.getStep30_2Data().setId(stepSpec.getStep30_2DataId());
			stepSpec.getStep30_2Operation().setId(stepSpec.getStep30_2OperationId());
			this.step30_2DataDao.saveOrUpdate(stepSpec.getStep30_2Data());
			this.step30_2DataDao.saveOrUpdate(stepSpec.getStep30_2Operation());
		}
		
		if(stepSpec.getStep80Data()!= null && stepSpec.getStep80Operation() != null){
			stepSpec.getStep80Data().setId(stepSpec.getStep80DataId());
			stepSpec.getStep80Operation().setId(stepSpec.getStep80OperationId());
			this.step80DataDao.saveOrUpdate(stepSpec.getStep80Data());
			this.step80DataDao.saveOrUpdate(stepSpec.getStep80Operation());
		}
		
		if(stepSpec.getStep140_1Data()!= null && stepSpec.getStep140_1Operation() != null){
			stepSpec.getStep140_1Data().setId(stepSpec.getStep140_1DataId());
			stepSpec.getStep140_1Operation().setId(stepSpec.getStep140_1OperationId());
			this.step140_1DataDao.saveOrUpdate(stepSpec.getStep140_1Data());
			this.step140_1DataDao.saveOrUpdate(stepSpec.getStep140_1Operation());
		}
		
		if(stepSpec.getStep140_2Data()!= null && stepSpec.getStep140_2Operation() != null){
			stepSpec.getStep140_2Data().setId(stepSpec.getStep140_2DataId());
			stepSpec.getStep140_2Operation().setId(stepSpec.getStep140_2OperationId());
			this.step140_2DataDao.saveOrUpdate(stepSpec.getStep140_2Data());
			this.step140_2DataDao.saveOrUpdate(stepSpec.getStep140_2Operation());
		}
		
		if(stepSpec.getStep160Data()!= null && stepSpec.getStep160Operation() != null){
			stepSpec.getStep160Data().setId(stepSpec.getStep160DataId());
			stepSpec.getStep160Operation().setId(stepSpec.getStep160OperationId());
			this.step160DataDao.saveOrUpdate(stepSpec.getStep160Data());
			this.step160DataDao.saveOrUpdate(stepSpec.getStep160Operation());
		}
		
		if(stepSpec.getStep170_1Data()!= null && stepSpec.getStep170_1Operation() != null){
			stepSpec.getStep170_1Data().setId(stepSpec.getStep170_1DataId());
			stepSpec.getStep170_1Operation().setId(stepSpec.getStep170_1OperationId());
			this.step170_1DataDao.saveOrUpdate(stepSpec.getStep170_1Data());
			this.step170_1DataDao.saveOrUpdate(stepSpec.getStep170_1Operation());
		}
		
		if(stepSpec.getStep170_2Data()!= null && stepSpec.getStep170_2Operation() != null){
			stepSpec.getStep170_2Data().setId(stepSpec.getStep170_2DataId());
			stepSpec.getStep170_2Operation().setId(stepSpec.getStep170_2OperationId());
			this.step170_2DataDao.saveOrUpdate(stepSpec.getStep170_2Data());
			this.step170_2DataDao.saveOrUpdate(stepSpec.getStep170_2Operation());
		}
	}
	
    public void deleteStepSpec(Long stepSpecId) {
    	StepSpec spec = this.getStepSpec(stepSpecId);
    	if(spec.getStep10_1DataId() != null)
    		this.step10_1DataDao.deleteByKey(spec.getStep10_1DataId());
    	if(spec.getStep10_1OperationId() != null)
    		this.step10_1DataDao.deleteByKey(spec.getStep10_1OperationId());
    	if(spec.getStep10_2DataId() != null)
    		this.step10_2DataDao.deleteByKey(spec.getStep10_2DataId());
    	if(spec.getStep10_2OperationId() != null)
    		this.step10_2DataDao.deleteByKey(spec.getStep10_2OperationId());
    	if(spec.getStep30_2DataId() != null)
    		this.step30_2DataDao.deleteByKey(spec.getStep30_2DataId());
    	if(spec.getStep30_2OperationId() != null)
    		this.step30_2DataDao.deleteByKey(spec.getStep30_2OperationId());
    	if(spec.getStep80DataId() != null)
    		this.step80DataDao.deleteByKey(spec.getStep80DataId());
    	if(spec.getStep80OperationId() != null)
    		this.step80DataDao.deleteByKey(spec.getStep80OperationId());
    	if(spec.getStep140_1DataId() != null)
    		this.step140_1DataDao.deleteByKey(spec.getStep140_1DataId());
    	if(spec.getStep140_1OperationId() != null)
    		this.step140_1DataDao.deleteByKey(spec.getStep140_1OperationId());
    	if(spec.getStep140_2DataId() != null)
    		this.step140_2DataDao.deleteByKey(spec.getStep140_2DataId());
    	if(spec.getStep140_2OperationId() != null)
    		this.step140_2DataDao.deleteByKey(spec.getStep140_2OperationId());
    	if(spec.getStep160DataId() != null)
    		this.step160DataDao.deleteByKey(spec.getStep160DataId());
    	if(spec.getStep160OperationId() != null)
    		this.step160DataDao.deleteByKey(spec.getStep160OperationId());
    	if(spec.getStep170_1DataId() != null)
    		this.step170_1DataDao.deleteByKey(spec.getStep170_1DataId());
    	if(spec.getStep170_1OperationId() != null)
    		this.step170_1DataDao.deleteByKey(spec.getStep170_1OperationId());
    	if(spec.getStep170_2DataId() != null)
    		this.step170_2DataDao.deleteByKey(spec.getStep170_2DataId());
    	if(spec.getStep170_2OperationId() != null)
    		this.step170_2DataDao.deleteByKey(spec.getStep170_2OperationId());
    	this.stepSpecDao.deleteByKey(stepSpecId);
    }
    
    private List<String> getLotSynProperties(Object obj){
    	List<String> result = new ArrayList<String>();
    	String key = null;
		if(obj instanceof Product)
			key = "lot.syn.product";
		else if(obj instanceof Step10_1Data)
			key = "lot.syn.step10_1";
		else if(obj instanceof Step10_2Data)
			key = "lot.syn.step10_2";
		else if(obj instanceof Step20Data)
			key = "lot.syn.step20";
		else if(obj instanceof Step30_1Data)
			key = "lot.syn.step30_1";
		else if(obj instanceof Step30_2Data)
			key = "lot.syn.step30_2";
		else if(obj instanceof Step40Data)
			key = "lot.syn.step40";
		else if(obj instanceof Step50Data)
			key = "lot.syn.step50";
		else if(obj instanceof Step60Data)
			key = "lot.syn.step60";
		else if(obj instanceof Step70Data)
			key = "lot.syn.step70";
		else if(obj instanceof Step80Data)
			key = "lot.syn.step80";
		else if(obj instanceof Step90Data)
			key = "lot.syn.step90";
		else if(obj instanceof Step100_1Data)
			key = "lot.syn.step100_1";
		else if(obj instanceof Step100_2Data)
			key = "lot.syn.step100_2";
		else if(obj instanceof Step100_3Data)
			key = "lot.syn.step100_3";
		else if(obj instanceof Step110Data)
			key = "lot.syn.step110";
		else if(obj instanceof Step120_1Data)
			key = "lot.syn.step120_1";
		else if(obj instanceof Step120_2Data)
			key = "lot.syn.step120_2";
		else if(obj instanceof Step130Data)
			key = "lot.syn.step130";
		else if(obj instanceof Step140_1Data)
			key = "lot.syn.step140_1";
		else if(obj instanceof Step140_2Data)
			key = "lot.syn.step140_2";
		else if(obj instanceof Step150Data)
			key = "lot.syn.step150";
		else if(obj instanceof Step160Data)
			key = "lot.syn.step160";
		else if(obj instanceof Step170_1Data)
			key = "lot.syn.step170_1";
		else if(obj instanceof Step170_2Data)
			key = "lot.syn.step170_2";
		else if(obj instanceof Step180Data)
			key = "lot.syn.step180";
		ResourceBundle configuation = ResourceBundle.getBundle("configuration", Locale.getDefault());
		try{
			String value = configuation.getString(key);
			if(value != null){
				StringTokenizer st = new StringTokenizer(value, ",");
				while(st.hasMoreTokens())
					result.add(st.nextToken().trim());
			}
		}catch(MissingResourceException e){
			log.warn("Missing configuration for the key: " + key);
		}
    	return result;
    }
    
	private void initLotProperties(Object newObject, Object lotObject, List<String> properties){
		if(newObject == null || lotObject == null || properties == null || properties.size() == 0)
			return;
		Field[] fields = newObject.getClass().getDeclaredFields();
		for(Field field : fields){
			if(!properties.contains(field.getName()))
				continue;
			String fieldName=field.getName();   
            String stringLetter=fieldName.substring(0, 1).toUpperCase(); 
            String getName="get"+stringLetter+fieldName.substring(1); 
            String setName="set"+stringLetter+fieldName.substring(1); 
            try {
				Method getMethod= newObject.getClass().getMethod(getName, new Class[]{});
				Method setMethod= newObject.getClass().getMethod(setName, new Class[]{String.class});
				setMethod.invoke(newObject, getMethod.invoke(lotObject, new Object[]{}));
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
	}
	
	public boolean lockProduct(Long productId, String user){
		Product product = this.productDao.get(productId);
		if(product.getLockedBy() != null && product.getLockedBy().length() > 0){
			if(product.getLockedBy().equals(this.userService.getCurrentUser().getUsername()))
				return true;
			else
				return false;
		}
		this.productDao.updateLockedBy(productId, user);
		return true;
	}
	
	public boolean unlockProduct(Long productId){
		Product product = this.productDao.get(productId);
		if(product.getLockedBy() == null || product.getLockedBy().length() == 0)
			return false;
		if(!this.userService.hasRole("Admin") && !product.getLockedBy().equals(this.userService.getCurrentUser().getUsername()))
			return false;
		this.productDao.updateLockedBy(productId, null);
		return true;
	}

	public boolean isRework() {
		return ConfigurationService.getInstance().isRework();
	}
	
	public boolean isAutoCreateSn() {
		return ConfigurationService.getInstance().isAutoCreateSn();
	}
	
	private String createSn(Long productId){
		StringBuffer sn = new StringBuffer("300");
		int dow = Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1;
		int year = Calendar.getInstance().get(Calendar.YEAR);
		String sequence = ("0000" + productId.toString()).substring(("0000" + productId.toString()).length() - 4);
		sn.append(dow);
		sn.append(new Long(year).toString().substring(2));
		sn.append(sequence);
		return sn.toString();
	}
	
	public void loadStep140TestingData(Long productId, Step140_1Data step){
		Product product = this.getProduct(productId);
		Step140IntegrationData testing =  this.step140IntegrationDataDao.getStep140IntegrationDataBySn(product.getInternalSn());
		if(testing == null)
			return;
		step.setTransParm2(testing.getTemperature());
		step.setIlParm2(null==testing.getPmaxil()?null:testing.getPmaxil().toString());
		step.setRipplelParm2(null==testing.getPripple()?null:testing.getPripple().toString());
		step.setIsolParm2(null==testing.getAdjiso()?null:testing.getAdjiso().toString());
		step.setIsorParm2(null==testing.getNonadjiso()?null:testing.getNonadjiso().toString());
		step.setRilrParm2(null==testing.getRiladj()?null:testing.getRiladj().toString());
		step.setRillParm2(null==testing.getRilnonadj()?null:testing.getRilnonadj().toString());
		step.setMinRisoParm2(null==testing.getRminiso()?null:testing.getRminiso().toString());
		step.setPbwParm2(null==testing.getDbbw()?null:testing.getDbbw().toString());
		step.setDcwlParm2(null==testing.getDcwl()?null:testing.getDcwl().toString());
	}

}
